Swaps raw pointer types with NonNull for better safety and niches#687
Swaps raw pointer types with NonNull for better safety and niches#687ErisianArchitect wants to merge 5 commits intoTheDan64:masterfrom
Conversation
|
Third times the charm, I guess. |
|
Oh, I forgot to mention, I also added a couple functions to support.
|
| #[repr(transparent)] | ||
| #[derive(Debug)] | ||
| pub struct OperandBundle<'ctx> { | ||
| bundle: Cell<LLVMOperandBundleRef>, |
There was a problem hiding this comment.
As far as I could tell, bundle did not need to be a Cell, so I changed that too.
| unsafe { *self.0.get_or_insert_with(|| LLVMCreateTargetMachineOptions()) } | ||
| unsafe { | ||
| self.0 | ||
| .get_or_insert_with(|| NonNull::new_unchecked(LLVMCreateTargetMachineOptions())) |
There was a problem hiding this comment.
This is honestly a little bit weird, but it works.
There was a problem hiding this comment.
Do you think The struct should just be initialized with LLVMCreateTargetMachineOptions? Or does it being Option make sense?
There was a problem hiding this comment.
I'm not sure. I can look into it. I'm not sure why it's an Option in the first place, I didn't want to focus on anything besides what I was working on. I didn't want to give you too much to review. I think the reason it's an Option is because it's nullable. But I'll find out for sure and get back to you.
There was a problem hiding this comment.
/// LLVM target machine options provide another way to create target machines,
/// used with [Target::create_target_machine_from_options].
///
/// The option structure exposes an additional setting (i.e., the target ABI)
/// and provides default values for unspecified settings.
#[llvm_versions(18..)]
#[derive(Default, Debug)]
pub struct TargetMachineOptions(Option<NonNull<LLVMOpaqueTargetMachineOptions>>);I guess I didn't have to look far after all. I'm not entirely sure what this documentation is saying, but I'll figure it out. Maybe it doesn't need to be an Option, maybe it does. But I think it's a good idea to figure out that reason so we can include that information with the documentation.
There was a problem hiding this comment.
Okay, I'm back again. From the looks of it, it seems that the reason that it's an Option is for some sort of lazy initialization. I'm not sure why...
[After some more digging while writing this comment]
I narrowed it down to this commit: https://github.com/TheDan64/inkwell/pull/483/changes#diff-05702e78430359853e5b38404035fa394540368bee185a2cdc936a62b9cd65b0R1493
Unfortunately, he doesn't explain his changes.
But looking at the code, there doesn't appear to be any reason that TargetMachineOptions needs lazy initialization. I can remove it if you want.
There was a problem hiding this comment.
I asked the robot just for the hell of it, and the robot claims that LLVMTargetMachineOptionsRef should never be null, so maybe it doesn't represent a default value of any sort. I'll look deeper, because I don't trust anything the robot says.
There was a problem hiding this comment.
Could you please open up a follow up issue? You're right that this PR is already big enough as is. Was mostly curious, it doesnt need immediate attention
There was a problem hiding this comment.
Sure, I can do that.
|
Oh, and one last note: I didn't apply this optimization to |
|
Looks cool, it'll take me a while to review it all |
| #[inline(always)] | ||
| pub(crate) const fn const_assert(assertion: bool) { | ||
| if !assertion { | ||
| panic!("Assertion Failed"); |
There was a problem hiding this comment.
Is it possible to be able to take a static string? Would be nice if the panic had more specific details
There was a problem hiding this comment.
Unfortunately, no, not at compile time. panic expects a format argument, and format args, but it can't perform formatting at compile time.
There was a problem hiding this comment.
The best recommendation is to include a comment with the assertion. It's marked with #[track_caller], so the error will appear at the location of the assertion.
Yeah, sorry about that, haha. I really did not expect this change to affect this many lines. |
Description
Many of the types used
LLVM*Reftypes, which are type aliases for*mut LLVM*. These pointers are null-checked before creating new instances of these types, so I thought it would make sense to useNonNullinstead so that there would be better safety guarantees, and it would enable these types to have at least one niche, allowing for this condition:size_of::<T>() == size_of::<Option<T>>() && align_of::<T>() == align_of::<Option<T>>().Related Issue
Closes #686
How This Has Been Tested
I finally figured out clippy, so I have a bash function that I run that runs clippy, runs all the tests, then runs cargo fmt. So all checks should hopefully pass on the first try. Fingers crossed.
It's quite a big update. It was extremely repetitive and tedious, but I think I got everything.
Option<Breaking Changes>
I'm pretty sure there are no breaking changes.
Checklist